package per.lance.easytomcat.handler;

import per.lance.easytomcat.annotation.RequestMapping;
import per.lance.easytomcat.controller.Controller;
import per.lance.easytomcat.net.HttpRequest;
import per.lance.easytomcat.net.HttpRespone;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Pattern;

/**
 * @author Lance Li
 * @date 7/9/2018 1:04 PM
 * @desc
 */
public class DynamicHandler implements Handler {
    String packageName = "per.lance.easytomcat.pers.lance.easystruct1.controller.";
    ArrayList<String> classNames = new ArrayList<String>();
    HashMap<String, Controller> controllerMap = new HashMap<String, Controller>();

    public DynamicHandler() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        String filePath = ClassLoader.getSystemResource("").getPath() + packageName.replace(".", "/");
        File dir = new File(filePath);
        File[] files = dir.listFiles();

        for (File file : files) {
            if (!file.getName().equals("Controller.class")) {
                String className = packageName + file.getName().replace(".class", "");
                classNames.add(className);
                Class controller = Class.forName(className);
                controllerMap.put(className, (Controller) controller.newInstance());
            }
        }
    }

    public boolean doHttpHandle(HttpRequest httpRequest, HttpRespone httpRespone) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException {
        String requestPath = httpRequest.getUri().getPath();
        String requestMethod = httpRequest.getMethod();

        for (String className : classNames) {
            Class controller = Class.forName(className);
            Method[] methods = controller.getMethods();
            for (Method method : methods) {
                RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
                if (requestMapping == null) continue;
                System.out.println(requestMapping.requestMethod() + requestMapping.requestMethod().getName());
                String urlValue =  requestMapping.value();
                boolean isMatch = Pattern.matches(urlValue, requestPath);
                if (requestMapping.requestMethod().getName().equals(requestMethod.toLowerCase())
                        && isMatch) {
                    method.invoke(controllerMap.get(className), httpRequest, httpRespone);
                    return true;
                }
            }
        }
        new StaticHandler().doStaticHandler(httpRequest, httpRespone);
        return false;

    }
}
